package gov.pbc.nn.kjgl.maintenance.view;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.bdf2.core.orm.ParseResult;
import com.bstek.dorado.annotation.DataProvider;
import com.bstek.dorado.annotation.DataResolver;
import com.bstek.dorado.annotation.Expose;
import com.bstek.dorado.core.Configure;
import com.bstek.dorado.data.entity.EntityState;
import com.bstek.dorado.data.entity.EntityUtils;
import com.bstek.dorado.data.provider.Criteria;
import com.bstek.dorado.data.provider.Page;
import com.bstek.dorado.uploader.DownloadFile;
import com.bstek.dorado.uploader.UploadFile;
import com.bstek.dorado.uploader.annotation.FileProvider;
import com.bstek.dorado.uploader.annotation.FileResolver;

import gov.pbc.nn.core.bdf.entity.Dept;
import gov.pbc.nn.core.dao.CommonHibernateDao;
import gov.pbc.nn.core.dao.CommonJdbcDao;
import gov.pbc.nn.core.dao.PbcnnCoreHibernateDao;
import gov.pbc.nn.core.utils.EntityRowMapperUtils;
import gov.pbc.nn.core.utils.SecurityUtils;
import gov.pbc.nn.kjgl.maintenance.entity.SysEntity;
import gov.pbc.nn.kjgl.maintenance.entity.SysInspection;
import gov.pbc.nn.kjgl.maintenance.entity.SysInspectionTask;
import gov.pbc.nn.kjgl.maintenance.entity.SysInspectionWeek;
import gov.pbc.nn.kjgl.maintenance.entity.SysMaterial;

/**
 * 系统巡检
 * 
 * @author Administrator
 * 
 */
@Component
public class SysInspectionPR {

	@Resource(name = CommonHibernateDao.BEAN_ID)
	private CommonHibernateDao hibernateDao;
	@Resource(name = CommonJdbcDao.BEAN_ID)
	private CommonJdbcDao jdbcDao;
	@Resource(name = PbcnnCoreHibernateDao.BEAN_ID)
	private PbcnnCoreHibernateDao coreHibernateDao;

	@DataProvider
	public void loadInspectionWeek(Page<SysInspectionWeek> page, Criteria criteria) {
		Calendar c = Calendar.getInstance();
		c.setFirstDayOfWeek(Calendar.SUNDAY);
		int d = c.get(Calendar.DAY_OF_WEEK);

	}

	@DataProvider
	public void loadSysEntities(Page<SysEntity> page, Criteria criteria) {
		DetachedCriteria dc = this.hibernateDao.buildDetachedCriteria(criteria, SysEntity.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("auditState", 2));
		Dept dept = (Dept) ContextHolder.getLoginUser().getDepts().get(0);
		Dept zzDept = (Dept) SecurityUtils.getZZByDept(dept);
		if (!Dept.NANNING.equals(zzDept.getId())) {
		dc.add(Restrictions.or(Restrictions.eq("deptId", dept.getId()), Restrictions.eq("operationDeptId", dept.getId())));
		}
		this.hibernateDao.pagingQuery(page, dc);
	}

	/**
	 * 根据系统信息加载巡检明细信息
	 * 
	 * @param page
	 * @param criteria
	 * @param sysId
	 */
	@DataProvider
	public void loadInspection(Page<SysInspection> page, Criteria criteria, String sysId) {
		DetachedCriteria dc = this.hibernateDao.buildDetachedCriteria(criteria, SysInspection.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("sysId", sysId));
		dc.add(Restrictions.eq("type", 0));
		this.hibernateDao.pagingQuery(page, dc);
	}

	/**
	 * 根据巡检任务加载巡检明细信息
	 * 
	 * @param page
	 * @param criteria
	 * @param taskId
	 */
	@DataProvider
	public void loadInspectionByTask(Page<SysInspection> page, Criteria criteria, String taskId) {
		DetachedCriteria dc = this.hibernateDao.buildDetachedCriteria(criteria, SysInspection.class);
		dc.add(Restrictions.eq("invalid", false));
		if (StringUtils.isNotEmpty(taskId)) {
			dc.add(Restrictions.eq("taskId", taskId));
			dc.add(Restrictions.eq("type", 1));
		} else {
			dc.add(Restrictions.eq("type", 0));
		}
		this.hibernateDao.pagingQuery(page, dc);
	}

	@DataProvider
	public List<SysMaterial> loadInspectionFiles(String inspectionId) {
		DetachedCriteria dc = DetachedCriteria.forClass(SysMaterial.class);
		dc.add(Restrictions.eq("invalid", false));
		dc.add(Restrictions.eq("ownerId", inspectionId));
		return (List<SysMaterial>) this.hibernateDao.query(dc);
	}

	@DataProvider
	public void loadInspectionTask(Page<SysInspectionTask> page, Criteria criteria) {
		String sql = "select t.* from t_sys_inspection_task t inner join t_sys_operation_staff s on t.SYS_ID_=s.SYS_ID_ where t.INVALID_=0 and s.INVALID_=0 and s.USERNAME_=:username ";
		final Map<String, Object> params = new HashMap<String, Object>();
		params.put("username", ContextHolder.getLoginUserName());
		ParseResult result = this.jdbcDao.parseCriteria(criteria, true, "t");
		if (result != null) {
			sql += result.getAssemblySql();
			params.putAll(result.getValueMap());
		}
		this.jdbcDao.pagingQuery(page, sql, new RowMapper<SysInspectionTask>() {

			@Override
			public SysInspectionTask mapRow(ResultSet rs, int rowNum) throws SQLException {
				SysInspectionTask task = EntityRowMapperUtils.get(SysInspectionTask.class, rs, rowNum);
				return task;
			}
		}, params);
	}

	@DataProvider
	public List<Map<String, Object>> loadSys(String filterValue) {
		String hql = "select new map(id as id,name as name) from " + SysEntity.class.getName()
				+ " where invalid=false and state=0 and auditState=2 ";
		if (StringUtils.isNotEmpty(filterValue)) {
			hql += " and name like :name";
			Map<String, Object> params = new HashMap<String, Object>();
			params.put("name", filterValue + "%");
			return this.hibernateDao.query(hql, params);
		}
		List<Map<String, Object>> list = this.hibernateDao.query(hql);
		return list;
	}

	@DataResolver
	@Transactional
	public void saveInspection(SysInspection inspection, List<SysMaterial> files) throws IOException {
		EntityState state = EntityUtils.getState(inspection);
		if (state == EntityState.NEW) {
			this.hibernateDao.save(inspection);
		} else if (state == EntityState.MODIFIED) {
			this.hibernateDao.update(inspection);
		}
		if (files != null) {
			for (SysMaterial sm : files) {
				state = EntityUtils.getState(sm);
				if (state == EntityState.NEW) {
					Path source = Paths.get(sm.getPath());
					Path target = Paths.get(Configure.getString("SYS_YUNWEI_FILE_UPLOAD_PATH"), "系統巡检");
					if (!Files.exists(target)) {
						target = Files.createDirectories(target);
					}
					target = target.resolve(UUID.randomUUID().toString());
					sm.setSysId(inspection.getSysId());
					sm.setSysName(inspection.getSysName());
					sm.setOwnerId(inspection.getId());
					sm.setPath(target.toString());
					sm.setType(1);// 文件类型：1，巡检
					this.hibernateDao.save(sm);
					Files.copy(source, target);
				}
			}
		}
	}

	/**
	 * 上传巡检文件。
	 * 
	 * @param file
	 * @return
	 * @throws IOException
	 */
	@FileResolver
	@Transactional
	public String uploadInspectionFile(UploadFile file, Map<String, Object> params) throws IOException {
		String fileId = UUID.randomUUID().toString();
		Path target = Paths.get(ContextHolder.getBdfTempFileStorePath(), fileId);
		Files.copy(file.getInputStream(), target);
		return target.toString();
		// Map<String, Object> result = new HashMap<String, Object>();
		// String inspectionId = (String) params.get("id");
		// String filename = file.getFileName();
		// if (StringUtils.isEmpty(inspectionId)) {
		// String fileId = UUID.randomUUID().toString();
		// Path target = Paths.get(ContextHolder.getBdfTempFileStorePath(),
		// fileId);
		// Files.copy(file.getInputStream(), target);
		// result.put("path", target.toString());
		// } else {
		// // 将文件保存到实际目录中
		// Path path =
		// Paths.get(Configure.getString("SYS_YUNWEI_FILE_UPLOAD_PATH"),
		// "系統巡检");
		// if (!Files.exists(path)) {
		// path = Files.createDirectories(path);
		// }
		// path = path.resolve(UUID.randomUUID().toString());
		// SysInspection inspection = (SysInspection)
		// this.hibernateDao.get(inspectionId, SysInspection.class);
		// SysMaterial material = new SysMaterial();

		// this.hibernateDao.save(material);
		//
		// File dest = Files.createFile(path).toFile();
		//
		// file.transferTo(dest);
		// result.put("fileId", material.getId());
		// }
		// return result;
	}

	@Expose
	@Transactional
	public void deleteFile(String sysMaterialId) throws IOException {
		SysMaterial ma = (SysMaterial) this.hibernateDao.get(sysMaterialId, SysMaterial.class);
		if (ma != null) {
			this.hibernateDao.delete(ma);
			Files.deleteIfExists(Paths.get(ma.getPath()));
		}
	}

	@Expose
	@Transactional
	public void deleteInspection(String id) throws IOException {
		this.hibernateDao.delete(id, SysInspection.class);
		List<SysMaterial> list = this.loadInspectionFiles(id);
		List<String> paths = new ArrayList<String>();
		for (SysMaterial sm : list) {
			this.hibernateDao.delete(sm);
			paths.add(sm.getPath());
		}
		for (String path : paths) {
			Files.deleteIfExists(Paths.get(path));
		}
	}

	/**
	 * 下载文件
	 * 
	 * @param eventId
	 * @return
	 * @throws FileNotFoundException
	 */
	@FileProvider
	public DownloadFile downloadFile(Map<String, Object> params) throws FileNotFoundException {
		String path = (String) params.get("path");
		String fileName = (String) params.get("fileName");
		File file = new File(path);
		DownloadFile df = new DownloadFile(file);
		df.setFileName(fileName);
		return df;
	}

}
